@--------------------------------------------------------------------------------------------------------
@ Fajl je napisan sa tabulacijom velicine 2 razmaka (podesiti editor radi preglednosti)
@ Komentari u ovom asembleru pocinju sa @ umjesto sa ;
@
@		Program prikazuje upotrebu virtuelne memorije kod ARM procesora, i to samo u varijanti
@		stranicenja u jednom nivou.	
@--------------------------------------------------------------------------------------------------------

.global _Reset

.equ							RAM,		0xA0000000											@ Pocetna fizicka adresa RAM memorije.
.equ							PAGE_SIZE,	0x100000										@ Velicina stranice u bajtovima.

.equ							PMT_ENTRY_CNT, 0x1000										@ Broj ulaza u PMT
.equ							STEP_BETWEEN_BLOCKS, 0x100000						
.equ							PMT_ENTRY_SIZE,	4												@ Velicina ulaza u PMT (u bajtovima).
.equ							PMT_SECTION, 0x402
.equ							PMT_USER, 0xC02
.equ							PMT_FAULT, 0														@ Ulaz nije popunjen

.equ							WORD_SIZE,	4														@ Velicina rijeci u bajtovima

.equ							MASK_CLEAR_MODE,	0x1F									@ Maska za brisanje moda rada iz CPSR
.equ							MASK_USER_MODE,	0x10										@ Maska za postavljanje korisnickog moda.
.equ							MASK_ABORT_MODE, 0x17										@ Maska za postavljanje abort moda.

.macro 						cpwait
									mrc 		p15, 0, r0, c2, c0, 0 					@ citanje proizvoljnog registra cp15
									mov 		r0, r0                					@ cekanje da se citanje koprocesora zavrsi
									sub 		pc, pc, #4            					@ skok na sledecu instrukciju
.endm

.text

@prekidne rutine

_Reset:						B 			resetInterrupt									@ Prekidna rutina za reset.
									B 			.
									B 			svcInterrupt										@ Prekidna rutina za swi (svc) - iz biblioteke stdla.a
									B 			prefetchAbortInterrupt					@ Prekidna rutina za prefetch abort
									B 			dataAbortInterrupt							@ Prekidna rutina za data abort
									B 			.
									B 			.
									B 			.


@--------------------------------------------------------------------------------------------------------
@
@		Prekidna rutina za prekid data abort
@
@--------------------------------------------------------------------------------------------------------
.func							dataAbortInterrupt
dataAbortInterrupt:
									push 		{r0, r1, r2, r3, r12, lr}				

									mcr 		p15, 0, r0, c6, c0, 0										
									
									bl 			processAbortInterrupt
									cmp			r0,#0
									beq			endData

									mcr			p15, 0, r0, c8, c6, 0

									pop 		{r0, r1, r2, r3, r12, lr}
									subs		pc, lr, #8											@ iret

endData:					
									mcr			p15, 0, r0, c8, c7, 0
									@mozda cpwait
									pop 		{r0, r1, r2, r3, r12, lr}

									b				loop														@ iret main

.endfunc

@--------------------------------------------------------------------------------------------------------
@
@		Prekidna rutina za prekid prefetch abort
@
@--------------------------------------------------------------------------------------------------------

.func							prefetchAbortInterrupt
prefetchAbortInterrupt:	
									push 		{r0, r1, r2, r3, r12, lr}

									mov			r0, lr
									bl 			processAbortInterrupt
									
									cmp			r0,#0
									beq			endPrefetch

									mcr			p15, 0,	r0, c6, c5, 0
									
									pop 		{r0, r1, r2, r3, r12, lr}									
									subs		pc, lr, #4											@ iret

endPrefetch:
									mcr			p15, 0, r0, c8, c7, 0
									@mozda cpwait
									pop 		{r0, r1, r2, r3, r12, lr}

									b				loop														@ iret main								
.endfunc



@--------------------------------------------------------------------------------------------------------
@
@		Prekidna rutina za prekid reset
@
@--------------------------------------------------------------------------------------------------------
	
.func							resetInterrupt
resetInterrupt:		
									@ Inicijalizacija stekova									
									ldr 		sp, =svcStackTop								@ Inicijalizovanje steka za supervizorski mod
									mrs 		r0, cpsr												@ Prelaz u abort mod rada radi inicijalizovanja SP.
									ldr 		r1, =0x04												@ U r0 je ostao sadrzaj CPSR za potrebe povratka
									orr 		r1, r0, r1											@	u supervizorski mod. 
									msr 		cpsr, r1
									ldr			sp, =abortStackTop							@ Inicijalizovanje steka za abort mod 
																													
									msr			cpsr, r0												@ Povratak u supervizorski mod rada.				
					
									ldr   	r0, =flashData									@	Adresa podataka u flesu sa koje se kopiraju
																													@	pocetne vrijednosti.
									ldr   	r1, =RAM												@ Adresa podataka u RAM na koju se kopiraju pocetne
																													@ vrijednosti.
									ldr   	r2, =dataSize										@	Broj bajtova koje treba iskopirati
									cmp   	r2, #0													@ (broj bajtova za kopiranje) > 0 ?
									ble 		nocopy										@	Ukoliko nema pocetnih vrijednosti koje treba kopirati
																													@ kopiranje se preskace.
									
copy:							ldr  		r4, [r0], #WORD_SIZE						@ Citanje jedne rijeci iz flash memorije 
									str  		r4, [r1], #WORD_SIZE						@ i upis te rijeci u RAM memoriju.
									subs  	r2, r2, #WORD_SIZE							@	Azurira se broj preostalih bajtova za kopiranje
									bgt			copy														@ if (broj preostalih bajtova za kopiranje) > 0)
																													@			then kopiraj jos (goto copy).
									
									@ Popunjavanje PMT tabele:						
nocopy:						ldr 		r0, =PMT
									mov			r1, #PMT_ENTRY_CNT												
									ldr 		r2, =PMT_SECTION
									mov 		r3, #STEP_BETWEEN_BLOCKS

pmtFill:					str			r2, [r0], #4
									add			r2, r2, r3
									subs 		r1, r1, #1											
									bne 		pmtFill										
									
									@ inicijalizacija sistema
 									bl			init
				
									ldr 		r0, =PMT												
									mcr 		p15,0,r0,c2,c0,0								@	Upisivanje adrese pocetka PMT u registar 2 cp15.
	
									ldr 		r0, =0x1
									mcr 		p15,0,r0,c3,c0,0								@ Upis vrijednosti u registar za kontrolu pristupa domenima.
									@enable MMU
									mrc 		p15,0,r0,c1,c0,0   																																				
									orr 		r0, r0, #0x1      							
									mcr 		p15,0,r0,c1,c0,0   							
																													
									cpwait																	
																													
									
loop:							bl 			main												@ uchitavanje fajla
									
									@ Prelazak u korisnicki mod rada																				
									mrs 		r0, cpsr											
									ldr 		r1, =MASK_CLEAR_MODE
									bic 		r0, r0, r1											
									ldr 		r1, =MASK_USER_MODE
									orr 		r0, r0, r1											
									msr 		spsr, r0																		
									@skok u izvrshavanje 
									movs		pc, #0x100000

									b 			.																@ Beskonacna petlja u kojoj procesor ceka reset ili gasenje.
.endfunc
 
.end
 
